﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

using System.Diagnostics;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;


/*
 * 通用的功能测试框架
 * 首先需要一个待测程序，输入参数，预期输出
 * 然后一个judger
 * 执行待测程序，得到输出
 * 将输出和预期输出给judger，由judger评判是否pass
 * 
 * 通过json提供配置参数，所以需要解析json获取相关数据
 * 
 */
namespace CommonFunctionTest_CSharp
{
    class Program
    {
        static string GetResult(string exename,string args)
        {
            string ret = "";
            Process proc = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = exename,
                    Arguments = args,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                }
            };

            proc.Start();
            while (!proc.StandardOutput.EndOfStream)
            {
                string line = proc.StandardOutput.ReadLine();
                ret = ret+line+"\n";
                //Console.WriteLine(line);
            }
            proc.Close();
            return ret;
        }
        static int CallJudger(string expertdata,string result,string judgername)
        {
            int ret = -1;

            string args = expertdata + " " + result;
            Process proc = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = judgername,
                    Arguments = args,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                }
            };

            proc.Start();
            proc.WaitForExit();
            ret = proc.ExitCode;
            proc.Close();
            if(ret != 0)
            {
                Console.WriteLine("experdata:" + expertdata);
                Console.WriteLine("result:" + result);
                Console.WriteLine("judger trate not match");
            }
            return ret;
        }
        static void RunTestCases(string exename,string args,string expertdata,string judgername)
        {
            string result = GetResult(exename, args);
            int ret ;
            ret = CallJudger(expertdata, result, judgername);
            if(ret == 0)
            {
                Console.WriteLine("pass");
            }
            else
            {
                Console.WriteLine("failed");
            }
        }

        static void ShowUsage()
        {
            string usage = "XXX.exe  XXX.json";
            Console.WriteLine(usage);
        }
        static void Main(string[] args)
        {
            if(args.Length!=1)
            {
                ShowUsage();
                return;
            }
            string filename = args[0];
            StreamReader file = File.OpenText(filename);            
            JsonTextReader reader = new JsonTextReader(file);
            string jsonstr = file.ReadToEnd();
            //Console.WriteLine(jsonstr);
            //JObject jsonObject = (JObject)JToken.ReadFrom(reader);
            try
            {
                JObject jsonObj = JObject.Parse(jsonstr);
                //Console.WriteLine(jsonObj["TestCases"].ToString());
                JArray testcases = JArray.Parse(jsonObj["TestCases"].ToString());
                for(int i=0;i<testcases.Count;i++)
                {
                    JObject tmp = JObject.Parse(testcases[i].ToString());
                    string exe = tmp["exe"].ToString();
                    string arguments = tmp["arguments"].ToString();
                    string expert = tmp["expert"].ToString();
                    string judger = tmp["judger"].ToString();
                    RunTestCases(exe, arguments, expert, judger);
                }

            }
            catch(Exception e)
            {
                Console.WriteLine("something wrong," + e.ToString());
            }
            

            file.Close();

        }
    }
}
